#pragma once
#include "Common.hpp"
#include <pthread.h>
#include "ThreadPool.hpp"
#define MAX_PENDING_LEN 15

// NoCopy类拷贝构造函数和赋值重载都已删掉
// 任何类继承该类就无法被拷贝
class TCPServer : public NoCopy
{
private:
    // 默认消息处理方式---回显
    static void DefaultMessageHandler(int sockfd, const InetAddr &client, const std::string &message)
    {
        ssize_t size = write(sockfd, message.c_str(), message.size());
        if (size == -1)
        {
            LOG(LogLevel::ERROR) << "write: [" << client.Info() << "]写入数据时出错! " << std::strerror(errno);
            exit(WRITE_ERROR);
        }
    }
    // 为客户端提供服务的函数
    void Service(int sockfd, const InetAddr &client)
    {
        char buffer[BUFFER_SIZE];
        int n;
        while ((n = read(sockfd, buffer, sizeof(buffer) - 1)) > 0)
        {
            buffer[n] = 0;
            LOG(LogLevel::INFO) << "[" << client.Info() << "]# " << buffer;
            _message_handler(sockfd, client, buffer);
        }
        if (n == -1)
        {
            LOG(LogLevel::ERROR) << "read: [" << client.Info() << "]读取数据时出错! " << std::strerror(errno);
            exit(READ_ERROR);
        }
        LOG(LogLevel::INFO) << "[" << client.Info() << "]已断开连接! ";
    }

    // 多线程实现的处理函数=============================================
    struct ThreadData
    {
        TCPServer* self;
        int sockfd;
        InetAddr client;
    };
    static void *ThreadHandler(void *args)
    {
        pthread_detach(pthread_self());
        ThreadData *data = static_cast<ThreadData *>(args);
        data->self->Service(data->sockfd, data->client);
        close(data->sockfd);
        return nullptr;
    }
    // ===============================================================
public:
    TCPServer(in_port_t port, message_handler_t message_handler = DefaultMessageHandler)
        : _message_handler(message_handler)
    {
        // 多进程实现方式下，避免等待子进程的推荐方式
        // signal(SIGCHLD, SIG_IGN);
        _listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_listen_sockfd == -1)
        {
            LOG(LogLevel::FATAL) << "socket: 套接字创建失败! " << std::strerror(errno);
            exit(SOCKET_ERROR);
        }

        InetAddr local(INADDR_ANY, port);
        int n = bind(_listen_sockfd, local.NetAddrPtr(), local.AddrLen());
        if (n == -1)
        {
            LOG(LogLevel::FATAL) << "bind: 绑定地址失败! " << std::strerror(errno);
            exit(BIND_ERROR);
        }
    }
    ~TCPServer()
    {
        close(_listen_sockfd);
    }
    void Run()
    {
        int n = listen(_listen_sockfd, MAX_PENDING_LEN);
        if (n == -1)
        {
            LOG(LogLevel::FATAL) << "listen: 设置监听套接字失败! " << std::strerror(errno);
            exit(LISTEN_ERROR);
        }
        LOG(LogLevel::INFO) << "监听套接字已就绪, 等待连接请求...";

        
        while (true)
        {
            InetAddr client;
            int sockfd = accept(_listen_sockfd, client.NetAddrPtr(), &client.AddrLen());
            client = InetAddr(client.NetAddr());
            if (sockfd == -1)
            {
                LOG(LogLevel::WARNING) << "accept: [" << client.Info() << "]建立连接失败! " << std::strerror(errno);
                continue;
            }
            LOG(LogLevel::INFO) << "accept: [" << client.Info() << "]建立连接成功! ";

            // 多进程===================================================================
            // int id = fork();
            // if(id < 0)
            // {
            //     // 创建子进程失败
            //     LOG(LogLevel::FATAL) << "fork: 子进程创建失败! " << std::strerror(errno);
            //     exit(FORK_ERROR);
            // }
            // else if(id == 0)
            // {
            //     // 子进程
            //     // 使用孙子进程, 避免等待子进程
            //     if(fork() > 0) exit(NORMAL);

            //     close(_listen_sockfd);
            //     Service(sockfd, client);
            //     exit(NORMAL);
            // }
            // else
            // {
            //     // 父进程
            //     close(sockfd);
            // }
            // 多进程===================================================================

            // 多线程===================================================================
            pthread_t thread;
            ThreadData data = {this, sockfd, client};
            pthread_create(&thread, nullptr, ThreadHandler, &data);
            // 多线程===================================================================

            // 线程池===================================================================
            // auto task = std::bind(&TCPServer::Service, this, sockfd, client);
            // ThreadPoolModule::ThreadPool<std::function<void()>>::GetInstance()->PushTask(task);
            // 线程池===================================================================
        }
    }

private:
    int _listen_sockfd;
    message_handler_t _message_handler; // 客户端消息的处理函数
};